package com.nayun.gjh.xiaokabanghou.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nayun.gjh.xiaokabanghou.common.*;
import com.nayun.gjh.xiaokabanghou.mapper.DiuzhaoMapper;
import com.nayun.gjh.xiaokabanghou.model.Diuzhao;
import com.nayun.gjh.xiaokabanghou.model.User;
import com.nayun.gjh.xiaokabanghou.mapper.UserMapper;
import com.nayun.gjh.xiaokabanghou.model.request.SafetyUpdateUserRequest;
import com.nayun.gjh.xiaokabanghou.model.request.SafetyUserRequest;
import com.nayun.gjh.xiaokabanghou.model.response.SafetyLoginResponse;
import com.nayun.gjh.xiaokabanghou.model.response.SafetyUserResponse;
import com.nayun.gjh.xiaokabanghou.service.UserService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.Executors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.*;
import java.util.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.regex.Pattern;

import static com.nayun.gjh.xiaokabanghou.constant.UserConstant.USER_LOGIN_KEY;
import static com.nayun.gjh.xiaokabanghou.constant.UserConstant.USER_SAFETY_KEY;

/**
* @author tsin0
* @description 针对表【user】的数据库操作Service实现
* @createDate 2024-02-03 16:54:55
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService {

    /**
     * 盐值，混淆密码
     */
    public static final String SALT = "XiaoKabangBygjh2024";

    @Resource
    private UserMapper userMapper;
    @Resource
    private DiuzhaoMapper diuzhaoMapper;

    private static final ConcurrentHashMap<String, String> verificationCodes = new ConcurrentHashMap<>();
    private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private static final Logger logger = LogManager.getLogger(CustomMailSender.class);


    @Override
    public String userLogin(String phone,HttpServletRequest httpServletRequest) throws Exception {
        //不为空
        if(phone==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"手机号码为空");
        }
        //纯数字
        boolean matches = Pattern.matches("\\d+", phone);
        if(!matches){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"不是手机号码格式");
        }
        //11位
        if(phone.length()!=11){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"长度不是11位");
        }
        //开头是1
        if (!phone.startsWith("1")) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"开头数字不合法");
        }
        //查库
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        //加密
        String safetyPhone = new DesUtil(SALT).encrypt(phone, "CBC");
        userQueryWrapper.eq("phone",safetyPhone);
        List<User> users1 = userMapper.selectList(userQueryWrapper);
        //库里没有
        if(users1.size()>1){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"数据数目大于1?");
        }
        if(users1.isEmpty()){
            User user = new User();
            user.setPhone(safetyPhone);
            user.setUid(String.valueOf(UUID.randomUUID()));
            user.setCreateTime(new Date());
            boolean save = this.save(user);
            if(!save){
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"新增用户失败");
            }
            userQueryWrapper.eq("phone",safetyPhone);
            User userFromMysql = userMapper.selectOne(userQueryWrapper);
            if(userFromMysql==null){
                throw new BusinessException(ErrorCode.DATA_NULL,"数据库没有该条数据");
            }
            //记录登录状态
            SafetyUserRequest safetyUserRequest = new SafetyUserRequest();
            safetyUserRequest.setUc(userFromMysql.getUid());
            httpServletRequest.getSession().setAttribute(USER_LOGIN_KEY, safetyUserRequest);
            return safetyUserRequest.getUc();
        }
        //库里有
        User userFromMysql = users1.get(0);
        SafetyUserRequest safetyUserRequest = new SafetyUserRequest();
        safetyUserRequest.setUc(userFromMysql.getUid());
        httpServletRequest.getSession().setAttribute(USER_LOGIN_KEY,safetyUserRequest);
        return safetyUserRequest.getUc();
    }

    @Override
    public Boolean updatecardInfor(SafetyUpdateUserRequest safetyUpdateUserRequest,SafetyUserRequest loginUser) throws Exception {
        String loginUserUid = loginUser.getUc();
        //查库
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("uid",loginUserUid);
        List<User> users1 = userMapper.selectList(userQueryWrapper);
        //库里没有
        if(users1.isEmpty()){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据库没有该条数据");
        }
        if(users1.size()>1){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据数目大于1?");
        }
        //库里有
        User userFromMysql = users1.get(0);
        Long id = userFromMysql.getId();
        String userName = safetyUpdateUserRequest.getUserName();
        if(!userName.isEmpty()){
            if(userName.length()>=16){
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"长度过长");
            }
        }else {
            userName=null;
        }
        String stuNumber = safetyUpdateUserRequest.getStuNumber();
        if(!stuNumber.isEmpty()){
            boolean matchesstuNumber = Pattern.matches("\\d+", stuNumber);
            if(!matchesstuNumber){
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"错误");
            }
        }
        String phone = safetyUpdateUserRequest.getPhone();
        //手机号
        //不为空
        //纯数字
        boolean matches = Pattern.matches("\\d+", phone);
        if(!phone.isEmpty()){
            if(!matches){
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"不是手机号码格式");
            }
            //11位
            if(phone.length()!=11){
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"长度不是11位");
            }
            //开头是1
            if (!phone.startsWith("1")) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"开头数字不合法");
            }
        }
        String cardcodeLeastsix = safetyUpdateUserRequest.getCardcodeLeastsix();
        //纯数字
        if(!cardcodeLeastsix.isEmpty()){
            boolean matches2 = Pattern.matches("\\d+", cardcodeLeastsix);
            if(!matches2){
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"不是校园卡号码格式");
            }
            if(cardcodeLeastsix.length()!=6){
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"长度不是6位");
            }
        }
        //加密
        String safetyStuNumber = new DesUtil(SALT).encrypt(stuNumber, "CBC");
        String safetycardcodeLeastsix = new DesUtil(SALT).encrypt(cardcodeLeastsix, "CBC");
        String safetyPhone = new DesUtil(SALT).encrypt(phone, "CBC");
        User user = new User();
        user.setId(id);
        user.setUserName(userName);
        user.setStuNumber(safetyStuNumber);
        user.setCardcodeLeastsix(safetycardcodeLeastsix);
        user.setPhone(safetyPhone);
        user.setUpdateTime(new Date());
        int result = userMapper.updateById(user);
        if(result<0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"新增记录失败");
        }
        return true;
    }

    @Override
    public SafetyUserResponse cardInfor(SafetyUserRequest loginUser) throws Exception {
        String loginUserUid = loginUser.getUc();
        //查库
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("uid",loginUserUid);
        List<User> users1 = userMapper.selectList(userQueryWrapper);
        //库里没有
        if(users1.isEmpty()){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据库没有该条数据");
        }
        if(users1.size()>1){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据数目大于1?");
        }
        //库里有
        User userFromMysql = users1.get(0);
        //解密
        String phone =new DesUtil(SALT).decrypt(userFromMysql.getPhone(), "CBC");
        String cardcodeLeastsix =new DesUtil(SALT).decrypt(userFromMysql.getCardcodeLeastsix(), "CBC");
        String stuNumber =new DesUtil(SALT).decrypt(userFromMysql.getStuNumber(), "CBC");
        SafetyUserResponse safetyUserResponse = new SafetyUserResponse();
        safetyUserResponse.setUc(userFromMysql.getUid());
        safetyUserResponse.setUserName(HideCharactersUtil.reservedFirstWord(userFromMysql.getUserName()));
        safetyUserResponse.setCardcodeLeastfour(HideCharactersUtil.convertToFourDigits(cardcodeLeastsix));
        safetyUserResponse.setPhone(HideCharactersUtil.phoneHideDigits(phone,3,7));
        safetyUserResponse.setStuNumber(HideCharactersUtil.stuNumberHideDigits(stuNumber,4,7));
        safetyUserResponse.setCardStatus(userFromMysql.getCardStatus());
        return safetyUserResponse;
    }

    @Override
    public Boolean cardStatusToRecord(SafetyUserRequest loginUser) throws Exception {
        String loginUserUid = loginUser.getUc();
        //查库
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("uid",loginUserUid);
        List<User> users1 = userMapper.selectList(userQueryWrapper);
        //库里没有
        if(users1.isEmpty()){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据库没有该条数据");
        }
        if(users1.size()>1){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据数目大于1?");
        }
        //库里有
        User userFromMysql = users1.get(0);
        //修改user表
        User user = new User();
        user.setId(userFromMysql.getId());
        user.setCardStatus(11);
        boolean update = this.updateById(user);
        if(!update){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"系统出现严重错误");
        }
            //修改DiuZhao
        String cardcodeLeastsix = userFromMysql.getCardcodeLeastsix();
        if(cardcodeLeastsix==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper<Diuzhao> cardQueryWrapper = new QueryWrapper<>();
        cardQueryWrapper.eq("status",11);
        cardQueryWrapper.eq("cardcode_leastsix",cardcodeLeastsix);
        List<Diuzhao> diuzhaosList = diuzhaoMapper.selectList(cardQueryWrapper);
        if(diuzhaosList.size()>1){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据数目大于1?");
        }

        if(diuzhaosList.isEmpty()){
            Diuzhao diuzhao2 = new Diuzhao();
            diuzhao2.setCardUid(String.valueOf(UUID.randomUUID()));
            diuzhao2.setDiuUid(loginUserUid);
            diuzhao2.setStatus(11);
            diuzhao2.setCreateTime(new Date());
            diuzhao2.setCardcodeLeastsix(cardcodeLeastsix);
            int insert = diuzhaoMapper.insert(diuzhao2);
            if(insert<1){
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"系统出现严重错误");
            }
            return true;
        }
        Diuzhao diuzhao2 = new Diuzhao();
        Diuzhao diuzhao = diuzhaosList.get(0);
        diuzhao2.setId(diuzhao.getId());
        diuzhao2.setStatus(11);
        diuzhao2.setDiuUid(loginUserUid);
        int insert = diuzhaoMapper.updateById(diuzhao2);
        if(insert<1){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"系统出现严重错误");
        }
        return true;
    }


    @Override
    public Boolean cardStatusToFind(SafetyUserRequest loginUser) throws Exception {
        String loginUserUid = loginUser.getUc();
        //查库
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("uid",loginUserUid);
        List<User> users1 = userMapper.selectList(userQueryWrapper);
        //库里没有
        if(users1.isEmpty()){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据库没有该条数据");
        }
        if(users1.size()>1){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据数目大于1?");
        }
        //库里有
        User userFromMysql = users1.get(0);
        //修改user表
        User user = new User();
        user.setId(userFromMysql.getId());
        user.setCardStatus(21);
        boolean update = this.updateById(user);
        if(!update){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"系统出现严重错误");
        }
        //修改DiuZhao
        QueryWrapper<Diuzhao> cardQueryWrapper = new QueryWrapper<>();
        cardQueryWrapper.eq("status",11);
        cardQueryWrapper.eq("diu_uid",userFromMysql.getUid());
        List<Diuzhao> diuzhaosList = diuzhaoMapper.selectList(cardQueryWrapper);
        if(diuzhaosList.size()>1){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据数目大于1?");
        }
        if(diuzhaosList.isEmpty()){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据库没有该条数据");
        }
        Diuzhao diuzhao2 = new Diuzhao();
        Diuzhao diuzhao = diuzhaosList.get(0);
        diuzhao2.setId(diuzhao.getId());
        diuzhao2.setStatus(21);
        diuzhao2.setUpdateTime(new Date());
        int insert = diuzhaoMapper.updateById(diuzhao2);
        if(insert<1){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"系统出现严重错误");
        }
        return true;
    }


    @Override
    public SafetyLoginResponse getSafetyUser(SafetyUserRequest loginUser) {
        String uc = loginUser.getUc();
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("uid",uc);
        List<User> userList = userMapper.selectList(userQueryWrapper);
        if(userList.isEmpty()){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据库没有该条数据");
        }
        if(userList.size()>1){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据数目大于1?");
        }
        //库里有
        User userFromMysql = userList.get(0);
        SafetyLoginResponse safetyLoginResponse = new SafetyLoginResponse();
        safetyLoginResponse.setUc(userFromMysql.getUid());
        return safetyLoginResponse;
    }

    @Override
    public String sendCode(SafetyUserRequest loginUser) throws Exception {
        String uc = loginUser.getUc();
        //查库
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("uid", uc);
        List<User> users1 = userMapper.selectList(userQueryWrapper);
        //库里没有
        if (users1.size() > 1) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "数据数目大于1?");
        }
        if (users1.isEmpty()) {
            throw new BusinessException(ErrorCode.DATA_NULL, "没有数据返回");
        }
        //库里有
        User userFromMysql = users1.get(0);
        String stuNumberC = userFromMysql.getStuNumber();
        if (stuNumberC == null || stuNumberC.isEmpty()) {
            return null;
        }
        //解密
        String stuNumber =new DesUtil(SALT).decrypt(stuNumberC, "CBC");
 //       String stuNumMail = "vm" + stuNumber + "@jzxy.edu.cn";
        String stuNumMail = "2018616908@qq.com";
        int sixSafetyCode = CustomMailSender.SafetyCheckMailSend(stuNumMail);
        String sixCode =  String.valueOf(sixSafetyCode);
        // 设置键值对
        addUserVerificationCode(uc, sixCode);
        System.out.println(sixCode);
        return stuNumMail;
    }

    @Override
    public String userSafetyCheck(String sixCode, SafetyUserRequest loginUser,HttpServletRequest httpServletRequest) throws Exception {
        //不为空
        if(sixCode==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"手机号码为空");
        }
        //纯数字
        boolean matches = Pattern.matches("\\d+", sixCode);
        if(!matches){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"不是手机号码格式");
        }
        //11位
        if(sixCode.length()!=6){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"长度不是11位");
        }
        //查库
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("uid",loginUser.getUc());
        List<User> users1 = userMapper.selectList(userQueryWrapper);
        //库里没有
        if(users1.size()>1){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"数据数目大于1?");
        }
        if(users1.isEmpty()){
            throw new BusinessException(ErrorCode.DATA_NULL, "没有数据返回");
        }
        String s = verificationCodes.get(loginUser.getUc());
        //验证码
        if (!sixCode.equals(s)) {
            return null;
        }
        //库里有
        User userFromMysql = users1.get(0);
        SafetyUserRequest safetyUserRequest = new SafetyUserRequest();
        safetyUserRequest.setUc(userFromMysql.getUid());
        httpServletRequest.getSession().setAttribute(USER_SAFETY_KEY,safetyUserRequest);
        return safetyUserRequest.getUc();
    }

    @Override
    public SafetyLoginResponse getSafetyUser2(SafetyUserRequest loginUser) {
        String uc = loginUser.getUc();
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("uid",uc);
        List<User> userList = userMapper.selectList(userQueryWrapper);
        if(userList.isEmpty()){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据库没有该条数据");
        }
        if(userList.size()>1){
            throw new BusinessException(ErrorCode.REPEATING_DATA,"数据数目大于1?");
        }
        //库里有
        User userFromMysql = userList.get(0);
        SafetyLoginResponse safetyLoginResponse = new SafetyLoginResponse();
        safetyLoginResponse.setUc(userFromMysql.getUid());
        return safetyLoginResponse;
    }

    public static void addUserVerificationCode(String uc, String code) {
        // 将校验码放入Map
        verificationCodes.put(uc, code);

        // 在10分钟后删除对应的校验码
        scheduler.schedule(() -> {
            String removedCode = verificationCodes.remove(uc);
            if (removedCode != null) {
                logger.info("{}的用户验证码已经失效",uc);
            }
        }, 30, TimeUnit.MINUTES);
    }
}




